/*
    Aufgabe 4) Rekursion und Zeichnen mit StdDraw
*/

import java.awt.*;
import java.util.Random;

public class Aufgabe4 {
    
    private static void waterFlow(int[][] map, int row, int col, int prevValue) {
        // preserve own value
        int value = map[row][col];

        // check own value
        if (value < prevValue) {
            // set own value accordingly
            map[row][col] = -1;
        } else return;

        if (value == prevValue) {
            // prevent recursion loops by setting value appropriately
            // not allowing subsequent recursive calls to infinitely
            // pass the same value
            value = Integer.MIN_VALUE;
        }

        // determine whether to search west
        if (row > 0) {
            waterFlow(map, row - 1, col, value);
        }
        // determine whether to search east
        if (row < map.length - 1) {
            waterFlow(map, row + 1, col, value);
        }
        // determine whether to search north
        if (col > 0) {
            waterFlow(map, row, col - 1, value);
        }
        // determine whether to search south
        if (col < map[row].length - 1) {
            waterFlow(map, row, col + 1, value);
        }
    }
    
    private static void drawMap(int[][] map) {
        // sanity checks
        if (map == null || map.length == 0)
            return;

        // init
        int size = map.length;
        // scale is chosen so that squares can neatly be drawn in
        // increments of 1
        StdDraw.setScale(0, size);
        StdDraw.clear();

        // loop grid
        for (int i = size - 1; i >= 0; i--) {
            for (int j = 0; j < size; j++) {
                // decide which color to use
                if (map[i][j] < 0)
                    StdDraw.setPenColor(Color.BLUE);
                else
                    StdDraw.setPenColor(Color.GREEN);
                // we specify the middle of the square, which is offset by half of the square
                StdDraw.filledSquare(j + .5d, size - 1 - i + .51d, .51d);
            }
        }
    }
    
    private static void printArray(int[][] inputArray) {
        for (int y = 0; y < inputArray.length; y++) {
            for (int x = 0; x < inputArray[y].length; x++) {
                System.out.print(inputArray[y][x] + "\t");
            }
            System.out.println();
        }
        System.out.println();
    }
    
    // generates random map for testing
    private static int[][] genMap(int size) {
        int[][] myMap = new int[size][size];
        Random myRand = new Random();
        int rand;
        double min, max, factor = 0.3;
        for (int y = 0; y < size; y++) {
            for (int x = 0; x < size; x++) {
                int manDistFromMiddle = Math.abs(x - size / 2) + Math.abs(y - size / 2);
                min = (size / 2 * 10 - manDistFromMiddle / 2 * 10) * (1.0 + factor);
                max = (size * 10 - manDistFromMiddle / 2 * 10) * (1.0 - factor);
                //System.out.println("min: " + min + " max: " + max);
                rand = myRand.nextInt((int) (max - min)) + (int) min;
                myMap[y][x] = rand;
            }
        }
        return myMap;
    }
    
    public static void main(String[] args) {
        
        int[][] map = {{9, 5, 2, 9, 6, 11, 7, 8, 9},
                {9, 6, 3, 4, 6, 11, 1, 1, 7},
                {6, 9, 8, 5, 10, 11, 1, 1, 6},
                {9, 7, 9, 7, 9, 3, 2, 6, 5},
                {9, 12, 8, 8, 20, 8, 6, 7, 8},
                {9, 12, 8, 5, 7, 9, 5, 7, 8},
                {6, 4, 8, 4, 9, 10, 5, 4, 3},
                {5, 3, 3, 4, 11, 10, 8, 9, 9},
                {2, 2, 6, 6, 9, 10, 10, 10, 9},
        };
        
        printArray(map);
        waterFlow(map, map.length / 2, map.length / 2, Integer.MAX_VALUE);
        System.out.println();
        printArray(map);
        drawMap(map);

        int size;
        while (true) {
            StdDraw.pause(8000);
            size = new Random().nextInt(100);
            map = genMap(size);
            map[size / 2][size / 2] = size * 10;
            printArray(map);
            System.out.println();
            waterFlow(map, map.length / 2, map.length / 2, Integer.MAX_VALUE);
            System.out.println();
            printArray(map);
            drawMap(map);
        }
    }
}

